﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XCommunity.Data;
using System.Xml.Linq;

namespace XCommunity.Frames
{
  public class BoardPersister
  {

    private BoardFrameDataProvider _dataProvider = new BoardFrameDataProvider();

    public BoardFrameDataProvider DataProvider
    {
      get { return _dataProvider; }
    }

    public virtual IDictionary<string, BoardFrame> LoadBoards( FrameService service, string configUri )
    {
      //UNDONE 没有专门的配置文件加载引擎
      XDocument configDocument = XDocument.Load( configUri );

      Dictionary<string, BoardFrame> _boards = new Dictionary<string, BoardFrame>();

      foreach ( var boardElement in configDocument.Root.Elements( "board" ) )
      {
        string boardType = boardElement.Attribute( "type" ).Value;//UNDONE 未检查重复属性
        string boardId = boardElement.Attribute( "id" ).Value;//UNDONE 未检查重复属性

        if ( string.IsNullOrEmpty( boardId ) )
          throw new Exception( "配置错误，元素board丢失了必需的属性id" );//UNDONE 强类型的异常
        if ( string.IsNullOrEmpty( boardType ) )
          throw new Exception( "配置错误，元素board丢失了必需的属性type" );//UNDONE 强类型的异常

        BoardFrame boardFrame = CreateBoard( service, boardType, boardId );

        Dictionary<string, string> boardSettings = new Dictionary<string, string>();

        foreach ( var setting in boardElement.Attributes() )
        {
          string name = setting.Name.LocalName;
          string value = setting.Value;

          if ( name == "type" || name == "id" )
            continue;

          if ( boardSettings.ContainsKey( name ) )
            throw new Exception( string.Format( "配置错误，发现重复属性{0}", name ) );//UNDONE 强类型的异常

          boardSettings.Add( name, value );
        }

        boardFrame.LoadSettings( boardSettings );

        _boards.Add( boardId, boardFrame );
      }

      return _boards;
    }

    protected virtual BoardFrame CreateBoard( FrameService service, string boardTypeName, string boardId )
    {
      Type boardType = Type.GetType( boardTypeName );

      if ( boardType == null )
        throw new Exception( string.Format( "配置错误，未能找到类型“{0}”", boardTypeName ) );

      if ( !boardType.IsSubclassOf( typeof( BoardFrame ) ) )
        throw new Exception( "配置错误，Board的类型必须从BoardFrame继承" );

      BoardFrame boardFrame = (BoardFrame) boardType.GetConstructor( new Type[] { typeof( FrameService ), typeof( string ) } ).Invoke( new object[] { service, boardId } );
      return boardFrame;
    }


  }
}
